home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / inetutil.1 / inetutil / inetutils-1.1 / libtelnet / krb4encpwd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-31  |  11.5 KB  |  450 lines

  1. /*-
  2.  * Copyright (c) 1992, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)krb4encpwd.c    8.3 (Berkeley) 5/30/95";
  36. #endif /* not lint */
  37.  
  38.  
  39. #ifdef    KRB4_ENCPWD
  40. /*
  41.  * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
  42.  * ALL RIGHTS RESERVED
  43.  *
  44.  * "Digital Equipment Corporation authorizes the reproduction,
  45.  * distribution and modification of this software subject to the following
  46.  * restrictions:
  47.  *
  48.  * 1.  Any partial or whole copy of this software, or any modification
  49.  * thereof, must include this copyright notice in its entirety.
  50.  *
  51.  * 2.  This software is supplied "as is" with no warranty of any kind,
  52.  * expressed or implied, for any purpose, including any warranty of fitness
  53.  * or merchantibility.  DIGITAL assumes no responsibility for the use or
  54.  * reliability of this software, nor promises to provide any form of
  55.  * support for it on any basis.
  56.  *
  57.  * 3.  Distribution of this software is authorized only if no profit or
  58.  * remuneration of any kind is received in exchange for such distribution.
  59.  *
  60.  * 4.  This software produces public key authentication certificates
  61.  * bearing an expiration date established by DIGITAL and RSA Data
  62.  * Security, Inc.  It may cease to generate certificates after the expiration
  63.  * date.  Any modification of this software that changes or defeats
  64.  * the expiration date or its effect is unauthorized.
  65.  *
  66.  * 5.  Software that will renew or extend the expiration date of
  67.  * authentication certificates produced by this software may be obtained
  68.  * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
  69.  * 94065, (415)595-8782, or from DIGITAL"
  70.  *
  71.  */
  72.  
  73. #ifdef HAVE_CONFIG_H
  74. #include <config.h>
  75. #endif
  76.  
  77. #include <sys/types.h>
  78. #include <arpa/telnet.h>
  79. #include <pwd.h>
  80. #include <stdio.h>
  81.  
  82. #include <des.h>
  83. #include <krb.h>
  84. #ifdef    __STDC__
  85. #include <stdlib.h>
  86. #endif
  87. #ifdef    NO_STRING_H
  88. #include <strings.h>
  89. #else
  90. #include <string.h>
  91. #endif
  92.  
  93. #include "encrypt.h"
  94. #include "auth.h"
  95. #include "misc.h"
  96.  
  97. int krb_mk_encpwd_req P((KTEXT, char *, char *, char *, char *, char *, char *));
  98. int krb_rd_encpwd_req P((KTEXT, char *, char *, u_long, AUTH_DAT *, char *, char *, char *, char *));
  99.  
  100. extern auth_debug_mode;
  101.  
  102. static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
  103.                       AUTHTYPE_KRB4_ENCPWD, };
  104. static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
  105.                     TELQUAL_NAME, };
  106.  
  107. #define    KRB4_ENCPWD_AUTH    0    /* Authentication data follows */
  108. #define    KRB4_ENCPWD_REJECT    1    /* Rejected (reason might follow) */
  109. #define KRB4_ENCPWD_ACCEPT    2    /* Accepted */
  110. #define    KRB4_ENCPWD_CHALLENGE    3    /* Challenge for mutual auth. */
  111. #define    KRB4_ENCPWD_ACK        4    /* Acknowledge */
  112.  
  113. #define KRB_SERVICE_NAME    "rcmd"
  114.  
  115. static    KTEXT_ST auth;
  116. static    char name[ANAME_SZ];
  117. static    char user_passwd[ANAME_SZ];
  118. static    AUTH_DAT adat = { 0 };
  119. #ifdef    ENCRYPTION
  120. static Block    session_key    = { 0 };
  121. #endif    /* ENCRYPTION */
  122. static Schedule sched;
  123. static char  challenge[REALM_SZ];
  124.  
  125.     static int
  126. Data(ap, type, d, c)
  127.     Authenticator *ap;
  128.     int type;
  129.     void *d;
  130.     int c;
  131. {
  132.         unsigned char *p = str_data + 4;
  133.     unsigned char *cd = (unsigned char *)d;
  134.  
  135.     if (c == -1)
  136.         c = strlen((char *)cd);
  137.  
  138.         if (0) {
  139.                 printf("%s:%d: [%d] (%d)",
  140.                         str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
  141.                         str_data[3],
  142.                         type, c);
  143.                 printd(d, c);
  144.                 printf("\r\n");
  145.         }
  146.     *p++ = ap->type;
  147.     *p++ = ap->way;
  148.     *p++ = type;
  149.         while (c-- > 0) {
  150.                 if ((*p++ = *cd++) == IAC)
  151.                         *p++ = IAC;
  152.         }
  153.         *p++ = IAC;
  154.         *p++ = SE;
  155.     if (str_data[3] == TELQUAL_IS)
  156.         printsub('>', &str_data[2], p - (&str_data[2]));
  157.         return(net_write(str_data, p - str_data));
  158. }
  159.  
  160.     int
  161. krb4encpwd_init(ap, server)
  162.     Authenticator *ap;
  163.     int server;
  164. {
  165.         char hostname[80], *cp, *realm;
  166.     C_Block skey;
  167.  
  168.     if (server) {
  169.         str_data[3] = TELQUAL_REPLY;
  170.     } else {
  171.         str_data[3] = TELQUAL_IS;
  172.         gethostname(hostname, sizeof(hostname));
  173.         realm = krb_realmofhost(hostname);
  174.         cp = strchr(hostname, '.');
  175.         if (*cp != NULL) *cp = NULL;
  176.         if (read_service_key(KRB_SERVICE_NAME, hostname, realm, 0,
  177.                     KEYFILE, (char *)skey)) {
  178.           return(0);
  179.         }
  180.     }
  181.     return(1);
  182. }
  183.  
  184.     int
  185. krb4encpwd_send(ap)
  186.     Authenticator *ap;
  187. {
  188.  
  189.     printf("[ Trying KRB4ENCPWD ... ]\n");
  190.     if (!UserNameRequested) {
  191.         return(0);
  192.     }
  193.     if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
  194.         return(0);
  195.     }
  196.  
  197.     if (!Data(ap, KRB4_ENCPWD_ACK, (void *)NULL, 0)) {
  198.         return(0);
  199.     }
  200.  
  201.     return(1);
  202. }
  203.  
  204.     void
  205. krb4encpwd_is(ap, data, cnt)
  206.     Authenticator *ap;
  207.     unsigned char *data;
  208.     int cnt;
  209. {
  210.     Session_Key skey;
  211.     Block datablock;
  212.     char  r_passwd[ANAME_SZ], r_user[ANAME_SZ];
  213.     char  lhostname[ANAME_SZ], *cp;
  214.     int r;
  215.     time_t now;
  216.  
  217.     if (cnt-- < 1)
  218.         return;
  219.     switch (*data++) {
  220.     case KRB4_ENCPWD_AUTH:
  221.         memmove((void *)auth.dat, (void *)data, auth.length = cnt);
  222.  
  223.         gethostname(lhostname, sizeof(lhostname));
  224.         if ((cp = strchr(lhostname, '.')) != 0)  *cp = '\0';
  225.  
  226.         if (r = krb_rd_encpwd_req(&auth, KRB_SERVICE_NAME, lhostname, 0, &adat, NULL, challenge, r_user, r_passwd)) {
  227.             Data(ap, KRB4_ENCPWD_REJECT, (void *)"Auth failed", -1);
  228.             auth_finished(ap, AUTH_REJECT);
  229.             return;
  230.         }
  231.         auth_encrypt_userpwd(r_passwd);
  232.         if (passwdok(UserNameRequested, UserPassword) == 0) {
  233.           /*
  234.            *  illegal username and password
  235.            */
  236.           Data(ap, KRB4_ENCPWD_REJECT, (void *)"Illegal password", -1);
  237.           auth_finished(ap, AUTH_REJECT);
  238.           return;
  239.         }
  240.  
  241.         memmove((void *)session_key, (void *)adat.session, sizeof(Block));
  242.         Data(ap, KRB4_ENCPWD_ACCEPT, (void *)0, 0);
  243.         auth_finished(ap, AUTH_USER);
  244.         break;
  245.  
  246.     case KRB4_ENCPWD_CHALLENGE:
  247.         /*
  248.          *  Take the received random challenge text and save
  249.          *  for future authentication.
  250.          */
  251.         memmove((void *)challenge, (void *)data, sizeof(Block));
  252.         break;
  253.  
  254.  
  255.     case KRB4_ENCPWD_ACK:
  256.         /*
  257.          *  Receive ack, if mutual then send random challenge
  258.          */
  259.  
  260.         /*
  261.          * If we are doing mutual authentication, get set up to send
  262.          * the challenge, and verify it when the response comes back.
  263.          */
  264.  
  265.         if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  266.           register int i;
  267.  
  268.           time(&now);
  269.           sprintf(challenge, "%x", now);
  270.           Data(ap, KRB4_ENCPWD_CHALLENGE, (void *)challenge, strlen(challenge));
  271.         }
  272.         break;
  273.         
  274.     default:
  275.         Data(ap, KRB4_ENCPWD_REJECT, 0, 0);
  276.         break;
  277.     }
  278. }
  279.  
  280.  
  281.     void
  282. krb4encpwd_reply(ap, data, cnt)
  283.     Authenticator *ap;
  284.     unsigned char *data;
  285.     int cnt;
  286. {
  287.     Session_Key skey;
  288.     KTEXT_ST krb_token;
  289.     Block enckey;
  290.     CREDENTIALS cred;
  291.     int r;
  292.     char        randchal[REALM_SZ], instance[ANAME_SZ], *cp;
  293.         char        hostname[80], *realm;
  294.  
  295.     if (cnt-- < 1)
  296.         return;
  297.     switch (*data++) {
  298.     case KRB4_ENCPWD_REJECT:
  299.         if (cnt > 0) {
  300.             printf("[ KRB4_ENCPWD refuses authentication because %.*s ]\r\n",
  301.                 cnt, data);
  302.         } else
  303.             printf("[ KRB4_ENCPWD refuses authentication ]\r\n");
  304.         auth_send_retry();
  305.         return;
  306.     case KRB4_ENCPWD_ACCEPT:
  307.         printf("[ KRB4_ENCPWD accepts you ]\n");
  308.         auth_finished(ap, AUTH_USER);
  309.         return;
  310.     case KRB4_ENCPWD_CHALLENGE:
  311.         /*
  312.          * Verify that the response to the challenge is correct.
  313.          */
  314.  
  315.         gethostname(hostname, sizeof(hostname));
  316.         realm = krb_realmofhost(hostname);
  317.         memmove((void *)challenge, (void *)data, cnt);
  318.         memset(user_passwd, 0, sizeof(user_passwd));
  319.         local_des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0);
  320.         UserPassword = user_passwd;
  321.         Challenge = challenge;
  322.         strcpy(instance, RemoteHostName);
  323.         if ((cp = strchr(instance, '.')) != 0)  *cp = '\0';
  324.  
  325.         if (r = krb_mk_encpwd_req(&krb_token, KRB_SERVICE_NAME, instance, realm, Challenge, UserNameRequested, user_passwd)) {
  326.           krb_token.length = 0;
  327.         }
  328.  
  329.         if (!Data(ap, KRB4_ENCPWD_AUTH, (void *)krb_token.dat, krb_token.length)) {
  330.           return;
  331.         }
  332.  
  333.         break;
  334.  
  335.     default:
  336.         return;
  337.     }
  338. }
  339.  
  340.     int
  341. krb4encpwd_status(ap, name, level)
  342.     Authenticator *ap;
  343.     char *name;
  344.     int level;
  345. {
  346.  
  347.     if (level < AUTH_USER)
  348.         return(level);
  349.  
  350.     if (UserNameRequested && passwdok(UserNameRequested, UserPassword)) {
  351.         strcpy(name, UserNameRequested);
  352.         return(AUTH_VALID);
  353.     } else {
  354.         return(AUTH_USER);
  355.     }
  356. }
  357.  
  358. #define    BUMP(buf, len)        while (*(buf)) {++(buf), --(len);}
  359. #define    ADDC(buf, len, c)    if ((len) > 0) {*(buf)++ = (c); --(len);}
  360.  
  361.     void
  362. krb4encpwd_printsub(data, cnt, buf, buflen)
  363.     unsigned char *data, *buf;
  364.     int cnt, buflen;
  365. {
  366.     char lbuf[32];
  367.     register int i;
  368.  
  369.     buf[buflen-1] = '\0';        /* make sure its NULL terminated */
  370.     buflen -= 1;
  371.  
  372.     switch(data[3]) {
  373.     case KRB4_ENCPWD_REJECT:    /* Rejected (reason might follow) */
  374.         strncpy((char *)buf, " REJECT ", buflen);
  375.         goto common;
  376.  
  377.     case KRB4_ENCPWD_ACCEPT:    /* Accepted (name might follow) */
  378.         strncpy((char *)buf, " ACCEPT ", buflen);
  379.     common:
  380.         BUMP(buf, buflen);
  381.         if (cnt <= 4)
  382.             break;
  383.         ADDC(buf, buflen, '"');
  384.         for (i = 4; i < cnt; i++)
  385.             ADDC(buf, buflen, data[i]);
  386.         ADDC(buf, buflen, '"');
  387.         ADDC(buf, buflen, '\0');
  388.         break;
  389.  
  390.     case KRB4_ENCPWD_AUTH:        /* Authentication data follows */
  391.         strncpy((char *)buf, " AUTH", buflen);
  392.         goto common2;
  393.  
  394.     case KRB4_ENCPWD_CHALLENGE:
  395.         strncpy((char *)buf, " CHALLENGE", buflen);
  396.         goto common2;
  397.  
  398.     case KRB4_ENCPWD_ACK:
  399.         strncpy((char *)buf, " ACK", buflen);
  400.         goto common2;
  401.  
  402.     default:
  403.         sprintf(lbuf, " %d (unknown)", data[3]);
  404.         strncpy((char *)buf, lbuf, buflen);
  405.     common2:
  406.         BUMP(buf, buflen);
  407.         for (i = 4; i < cnt; i++) {
  408.             sprintf(lbuf, " %d", data[i]);
  409.             strncpy((char *)buf, lbuf, buflen);
  410.             BUMP(buf, buflen);
  411.         }
  412.         break;
  413.     }
  414. }
  415.  
  416. int passwdok (name, passwd)
  417.      char *name, *passwd;
  418. {
  419.   char *salt, *p;
  420.   struct passwd *pwd;
  421.   int   passwdok_status = 0;
  422.  
  423.   if (pwd = getpwnam(name))
  424.     salt = pwd->pw_passwd;
  425.   else salt = "xx";
  426.  
  427.   p = CRYPT (passwd, salt);
  428.  
  429.   if (pwd && !strcmp(p, pwd->pw_passwd)) {
  430.     passwdok_status = 1;
  431.   } else passwdok_status = 0;
  432.   return(passwdok_status);
  433. }
  434.  
  435. #endif
  436.  
  437. #ifdef notdef
  438.  
  439. prkey(msg, key)
  440.     char *msg;
  441.     unsigned char *key;
  442. {
  443.     register int i;
  444.     printf("%s:", msg);
  445.     for (i = 0; i < 8; i++)
  446.         printf(" %3d", key[i]);
  447.     printf("\r\n");
  448. }
  449. #endif
  450.